package com.doge.calcalbum.business.sysalbum

import android.provider.MediaStore
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.doge.calcalbum.core.base.LoadStatus
import com.doge.calcalbum.db.model.Album
import com.doge.calcalbum.db.model.AlbumCover
import com.doge.calcalbum.db.model.Entry
import com.doge.calcalbum.utils.*
import java.io.File

class SysAlbumRepository {
    private val pictureList = MutableLiveData<List<Pair<String, String>>>()
    val sysPictureList: LiveData<List<Pair<String, String>>> = pictureList
    val initPictureLoading = MutableLiveData<LoadStatus>()
    private val videoList = MutableLiveData<List<Pair<String, String>>>()
    val sysVideoList: LiveData<List<Pair<String, String>>> = videoList
    val initVideoLoading = MutableLiveData<LoadStatus>()
    val copyLoading = MutableLiveData<LoadStatus>()

    fun refresh() {
        val isGrantedPermission = checkPermission(
            listOf(
                android.Manifest.permission.READ_EXTERNAL_STORAGE,
                android.Manifest.permission.WRITE_EXTERNAL_STORAGE
            )
        )
        log("SysAlbumRepository refresh isGrantedPermission $isGrantedPermission")
        if (isGrantedPermission) {
            querySysPictures()
            querySysVideos()
        }
    }

    private fun querySysPictures() = runOnIO {
        runOnUI { initPictureLoading.value = LoadStatus.LOADING }
        val columns = arrayOf(MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID)
        val orderBy = MediaStore.Images.Media.DATE_MODIFIED
        val cursor = appContext.contentResolver.query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            columns, null, null, orderBy
        )
        val result = mutableListOf<Pair<String, String>>()
        if (cursor != null) {
            if (cursor.count > 0) {
                var size = 0
                while (cursor.moveToNext()) {
                    val dataColumnIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA)
                    val path = cursor.getString(dataColumnIndex)
                    result.add(Pair(File(path).parentFile?.name ?: "Pictures", path))
                    size++
                }
            }
            cursor.close()
        }

        runOnUI {
            pictureList.value = result.reversed()
            initPictureLoading.value = LoadStatus.SUCCESS
            initPictureLoading.value = LoadStatus.IDLE
        }
    }

    fun copyToAlbum(entries: List<SysEntry>, albumId: Int, albumType: Int, deleteOrigin: Boolean) =
        runOnIO {
            if (entries.isEmpty()) return@runOnIO
            runOnUI { copyLoading.value = LoadStatus.LOADING }
            val safeList = entries.filter {
                val inputFile = File(it.filePath)
                inputFile.exists().also {
                    if (!it) {
                        val sub = if (albumType == Album.TYPE_PICTURE) MediaStore.Images.Media.DATA
                        else MediaStore.Video.Media.DATA
                        val url =
                            if (albumType == Album.TYPE_PICTURE) MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                            else MediaStore.Video.Media.EXTERNAL_CONTENT_URI
                        val res = appContext.contentResolver.delete(
                            url, sub + "= \"" + inputFile.absolutePath + "\"", null
                        )
                        if (res > 0) inputFile.delete()
                    }
                }
            }
            val dataList = safeList.map {
                val inputFile = File(it.filePath)
                val outputFile = File(
                    Album.albumFileDir(albumId),
                    "${System.currentTimeMillis()}${inputFile.name}"
                ).also { file ->
                    if (!file.exists()) file.createNewFile()
                }
                FileUtils.copy(inputFile.inputStream(), outputFile.outputStream())
                Entry(
                    albumId = albumId,
                    filePath = outputFile.absolutePath,
                    fileSize = outputFile.length(),
                    createTime = System.currentTimeMillis(),
                    deleteTime = 0,
                )
            }

            runInTransaction {
                dataList.forEach(db.entryDao()::insert)
                db.albumDao().updateCount(albumId)

                if (db.albumDao().queryById(albumId)?.coverEntryId == null) {
                    db.entryDao().queryOne(albumId).let {
                        db.albumDao().updateCover(AlbumCover(albumId, it?.id))
                    }
                }

                if (deleteOrigin) {
                    runOnIO {
                        val sub = if (albumType == Album.TYPE_PICTURE) MediaStore.Images.Media.DATA
                        else MediaStore.Video.Media.DATA
                        val url =
                            if (albumType == Album.TYPE_PICTURE) MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                            else MediaStore.Video.Media.EXTERNAL_CONTENT_URI
                        safeList.forEach {
                            val res = appContext.contentResolver.delete(
                                url, sub + "= \"" + it.filePath + "\"", null
                            )
                            if (res > 0) File(it.filePath).delete()
                        }
                        if (albumType == Album.TYPE_PICTURE) {
                            pictureList.postValue(pictureList.value?.removeIf { sys ->
                                dataList.any { it.filePath == sys.second }
                            })
                        } else if (albumType == Album.TYPE_VIDEO) {
                            videoList.postValue(videoList.value?.removeIf { sys ->
                                dataList.any { it.filePath == sys.second }
                            })
                        }

                        runOnUI {
                            copyLoading.value = LoadStatus.SUCCESS
                            copyLoading.value = LoadStatus.IDLE
                        }
                    }
                } else {
                    runOnUI {
                        copyLoading.value = LoadStatus.SUCCESS
                        copyLoading.value = LoadStatus.IDLE
                    }
                }
            }
        }

    //////////////////////////////////////////

    private fun querySysVideos() = runOnIO {
        runOnUI { initVideoLoading.value = LoadStatus.LOADING }
        val columns = arrayOf(MediaStore.Video.Media.DATA, MediaStore.Video.Media._ID)
        val orderBy = MediaStore.Video.Media.DATE_MODIFIED
        val cursor = appContext.contentResolver.query(
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
            columns, null, null, orderBy
        )
        val result = mutableListOf<Pair<String, String>>()
        if (cursor != null) {
            if (cursor.count > 0) {
                var size = 0
                while (cursor.moveToNext()) {
                    val dataColumnIndex = cursor.getColumnIndex(MediaStore.Video.Media.DATA)
                    val path = cursor.getString(dataColumnIndex)
                    result.add(Pair(File(path).parentFile?.name ?: "Videos", path))
                    size++
                }
            }
            cursor.close()
        }

        runOnUI {
            videoList.value = result.reversed()
            initVideoLoading.value = LoadStatus.SUCCESS
            initVideoLoading.value = LoadStatus.IDLE
        }
    }

    companion object {
        private var INS: SysAlbumRepository? = null
        fun get(): SysAlbumRepository {
            return INS ?: synchronized(this) {
                INS ?: SysAlbumRepository().also { INS = it }
            }
        }
    }
}


private fun <T> List<T>.removeIf(
    condition: (T) -> Boolean
): List<T> {
    val list = toMutableList()
    val i = list.iterator()
    while (i.hasNext()) {
        if (condition(i.next())) i.remove()
    }
    return list
}
///storage/emulated/0/DCIM/Camera/WechatIMG59.jpeg
///storage/emulated/0/Pictures/QQ/qxlarge-dsc-2C40081E26FBFDA5595A77C41B11C14B.webp
///storage/emulated/0/Pictures/QQ/qxlarge-dsc-00940280C2AB8F2BAB2C362324485586.webp
///storage/emulated/0/Pictures/QQ/qxlarge-dsc-0E1B63ADA1DF681ADC8C347A6AA2C46F.webp
///storage/emulated/0/Tencent/QQ_Images/-6c2a783e2317bfb3.jpg
///storage/emulated/0/netease/cloudmusic/Cache/FlashSongs/flash_1430652542/flash_1430652542.zip_unzipdir/flashResources_android/flashOff.webp
///storage/emulated/0/netease/cloudmusic/Cache/FlashSongs/flash_1430652542/flash_1430652542.zip_unzipdir/flashResources_android/flashOn.webp
///storage/emulated/0/DCIM/Camera/1619607252759.jpg
///storage/emulated/0/Tencent/QQ_Images/40ea3ba1a24efc17.jpg
///storage/emulated/0/jiguang/jshare_jiguang_test_img.png
///storage/emulated/0/DCIM/Screenshots/Screenshot_20210409-151000_One UI Home.jpg
///storage/emulated/0/DCIM/Screenshots/Screenshot_20210409-150640_One UI Home.jpg
///storage/emulated/0/DCIM/Screenshots/Screenshot_20210409-150624_One UI Home.jpg
///storage/emulated/0/DCIM/Screenshots/Screenshot_20210409-150532_One UI Home.jpg
///storage/emulated/0/DCIM/Screenshots/Screenshot_20210409-150511_One UI Home.jpg
///storage/emulated/0/DCIM/Screenshots/Screenshot_20210409-150450_One UI Home.jpg
///storage/emulated/0/DCIM/Screenshots/Screenshot_20210409-150444_One UI Home.jpg
///storage/emulated/0/DCIM/Screenshots/Screenshot_20210409-150438_One UI Home.jpg
///storage/emulated/0/DCIM/Screenshots/Screenshot_20210409-150343_One UI Home.jpg
///storage/emulated/0/DCIM/Screenshots/Screenshot_20210409-143115_One UI Home.jpg
///storage/emulated/0/beauty/demo/v0104/Koi_2/Asset/UI/Textures/SettlementInterface/BG.png
///storage/emulated/0/DCIM/Camera/20201201_144448.jpg